/**
 * 
 */
package com.game.jumpdino.logic;

import java.util.ArrayList;
import java.util.List;

import android.graphics.Point;
import android.graphics.Rect;

import com.game.jumpdino.R;
import com.game.jumpdino.logic.visual.Avatar;
import com.game.jumpdino.logic.visual.HoldOnInformation;
import com.game.jumpdino.logic.visual.Holder;
import com.game.jumpdino.logic.visual.VisualBase;

/**
 * @author guhu
 * 
 */
public class VisualConfig {
	private static VisualConfig blockerConfig;
	private static VisualConfig holderConfig;
	private static VisualConfig fastHolderConfig;
	private static VisualConfig movingHolderConfig;
	private static VisualConfig flyingHolderConfig;
	private static VisualConfig onceHolderConfig;
	private static VisualConfig badHolderConfig;
	private static VisualConfig speedupConfig;
	private static VisualConfig slowdownConfig;
	private static VisualConfig avatarConfig;

	public int imgID;
	public int sndID;
	public int renderWidth;
	public int renderHeight;
	public VisualType type;
	public HoldOnInformation holdOn;
	public Velocity initialVelocity;
	public Rect hitTestArea;
	public float avatarSpeedUp;
	public float showUpRate;
	public int showUpScore;
	public int maxShowUpCount;
	public int showedCount;
	// No limit to effect time by default.
	public int effectTime = -1;
	public VisualEventListener mVisualEventListener;

	/**
	 * @return the mVisualEventListener
	 */
	public VisualEventListener getmVisualEventListener() {
		return mVisualEventListener;
	}

	public Rect getHitTestArea() {
		return hitTestArea;
	}

	public Rect setHitTestArea(Rect hitTestArea) {
		Rect previous = this.hitTestArea;
		this.hitTestArea = hitTestArea;
		return previous;
	}

	/**
	 * @param mVisualEventListener
	 *            the mVisualEventListener to set
	 */
	public void setmVisualEventListener(VisualEventListener mVisualEventListener) {
		this.mVisualEventListener = mVisualEventListener;
	}

	public void Reset() {
		showedCount = 0;
	}

	public static VisualConfig getBlockerConfig() {
		if (blockerConfig == null) {
			blockerConfig = new VisualConfig();
			blockerConfig.imgID = R.drawable.dragon2;
			blockerConfig.type = VisualType.Blocker;
			blockerConfig.initialVelocity = new Velocity(5, 0);
			blockerConfig.showUpRate = 0.05f;
			blockerConfig.maxShowUpCount = 1;
			blockerConfig.avatarSpeedUp = 1.2f;
			blockerConfig.effectTime = 1;
			blockerConfig.showUpScore = 9000000;
			blockerConfig.hitTestArea = new Rect(5, 5, 115, 50);
		}
		return blockerConfig;
	}

	public static VisualConfig getHolderConfig() {
		if (holderConfig == null) {
			holderConfig = new VisualConfig();
			holderConfig.imgID = R.drawable.hill;
			holderConfig.sndID = R.raw.jmpsnd;
			holderConfig.type = VisualType.Holder;
			holderConfig.initialVelocity = new Velocity(0, 0);
			holderConfig.avatarSpeedUp = 1;
			holderConfig.effectTime = -1;
			holderConfig.showUpRate = 0.5f;
			holderConfig.maxShowUpCount = 0;
			holderConfig.showUpScore = 0;
			holderConfig.hitTestArea = new Rect(1, 1, 79, 6);
		}

		return holderConfig;
	}

	public static VisualConfig getMovingHolderConfig() {
		if (movingHolderConfig == null) {
			movingHolderConfig = new VisualConfig();
			movingHolderConfig.imgID = R.drawable.hill;
			movingHolderConfig.type = VisualType.Holder;
			movingHolderConfig.sndID = R.raw.jmpsnd;
			movingHolderConfig.initialVelocity = new Velocity(10, 0);
			movingHolderConfig.avatarSpeedUp = 1;
			movingHolderConfig.effectTime = -1;
			movingHolderConfig.showUpRate = 0.5f;
			movingHolderConfig.maxShowUpCount = 2;
			movingHolderConfig.showUpScore = 15000;
			movingHolderConfig.hitTestArea = new Rect(1, 1, 79, 6);
		}

		return movingHolderConfig;
	}

	public static VisualConfig getFastHolderConfig() {
		if (fastHolderConfig == null) {
			fastHolderConfig = new VisualConfig();
			fastHolderConfig.imgID = R.drawable.cloud;
			fastHolderConfig.type = VisualType.CloudHolder;
			fastHolderConfig.initialVelocity = new Velocity(0, 0);
			fastHolderConfig.avatarSpeedUp = 1.8f;
			fastHolderConfig.effectTime = -1;
			fastHolderConfig.showUpRate = 0.1f;
			fastHolderConfig.maxShowUpCount = 1;
			fastHolderConfig.showUpScore = 20000;
			fastHolderConfig.sndID = R.raw.flysnd;
			fastHolderConfig.hitTestArea = new Rect(0, 0, 110, 60);
			fastHolderConfig.holdOn = new HoldOnInformation(new Point(0, 48));
		}

		return fastHolderConfig;
	}

	public static VisualConfig getSpeedUpConfig() {
		if (speedupConfig == null) {
			speedupConfig = new VisualConfig();
			speedupConfig.imgID = R.drawable.speeduptool;
			speedupConfig.type = VisualType.Holder;
			speedupConfig.initialVelocity = new Velocity(-10, 0);
			speedupConfig.avatarSpeedUp = 1;
			speedupConfig.effectTime = 1;
			speedupConfig.showUpRate = 0.1f;
			speedupConfig.maxShowUpCount = 1;
			speedupConfig.showUpScore = 5000;
			speedupConfig.sndID = R.raw.jmpsnd;
			speedupConfig.hitTestArea = new Rect(0, 0, 46, 46);
			speedupConfig.holdOn = new HoldOnInformation(new Point(-15, 50));
			speedupConfig.mVisualEventListener = new VisualEventListener() {
				private List<VisualBase> hits = new ArrayList<VisualBase>();

				public void onHit(VisualBase who, VisualBase visual,
						Playground ground) {
					if (!hits.contains(who) && !ground.avatar.isHasTool()) {
						final VisualBase a = (Avatar) visual;
						hits.add(who);
						VisualBase.setMinSpeedUp(-50);
						a.setG(1);

						Thread splashTread = new Thread() {
							@Override
							public void run() {
								try {
									Thread.sleep(15000);
								} catch (InterruptedException e) {
									// do nothing
								} finally {
									VisualBase
											.setMinSpeedUp(VisualBase.defaultJumpSpeed);
									a.setG(Avatar.defaultG);
								}
							}
						};
						splashTread.start();
					}
				}

				public void onMove(VisualBase who, float offsetX, float offsetY) {

				}

				public void onRemoved(VisualBase who) {
					hits.remove(who);
				}
			};
		}

		return speedupConfig;
	}

	public static VisualConfig getSlowdownConfig() {
		if (slowdownConfig == null) {
			slowdownConfig = new VisualConfig();
			slowdownConfig.imgID = R.drawable.umbrella;
			slowdownConfig.type = VisualType.Umbrella;
			slowdownConfig.initialVelocity = new Velocity(-1, 0);
			slowdownConfig.avatarSpeedUp = 1;
			slowdownConfig.effectTime = 1;
			slowdownConfig.showUpRate = 0.1f;
			slowdownConfig.maxShowUpCount = 1;
			slowdownConfig.showUpScore = 20000000;
			slowdownConfig.sndID = R.raw.jmpsnd;
			slowdownConfig.hitTestArea = new Rect(0, 0, 58, 46);
			slowdownConfig.holdOn = new HoldOnInformation(new Point(-10, 50));
		}

		return slowdownConfig;
	}

	public static VisualConfig getBadHolderConfig() {
		if (badHolderConfig == null) {
			badHolderConfig = new VisualConfig();
			badHolderConfig.imgID = R.drawable.reverse;
			badHolderConfig.type = VisualType.Holder;
			badHolderConfig.initialVelocity = new Velocity(-5, 0);
			badHolderConfig.avatarSpeedUp = 1f;
			badHolderConfig.effectTime = 1;
			badHolderConfig.showUpRate = 0.3f;
			badHolderConfig.maxShowUpCount = 1;
			badHolderConfig.sndID = R.raw.jmpsnd;
			badHolderConfig.showUpScore = 15000;
			badHolderConfig.hitTestArea = new Rect(0, 0, 44, 32);
			badHolderConfig.holdOn = new HoldOnInformation(new Point(-25, 50));
			badHolderConfig.mVisualEventListener = new VisualEventListener() {
				public void onHit(VisualBase who, VisualBase visual,
						Playground ground) {
					if (who instanceof Holder) {
						ground.setReverseOperation(ground.getReverseOperation()
								* -1);
					}
				}

				public void onMove(VisualBase who, float offsetX, float offsetY) {
					// Do nothing.
				}

				public void onRemoved(VisualBase who) {
				}
			};
		}

		return badHolderConfig;
	}

	public static VisualConfig getOnceHolderConfig() {
		if (onceHolderConfig == null) {
			onceHolderConfig = new VisualConfig();
			onceHolderConfig.imgID = R.drawable.hill2;
			onceHolderConfig.sndID = R.raw.jmpsnd;
			onceHolderConfig.type = VisualType.BreakHolder;
			onceHolderConfig.initialVelocity = new Velocity(0, 0);
			onceHolderConfig.avatarSpeedUp = 0;
			onceHolderConfig.effectTime = -1;
			onceHolderConfig.showUpRate = 0.3f;
			onceHolderConfig.maxShowUpCount = 2;
			onceHolderConfig.showUpScore = 30000;
			onceHolderConfig.hitTestArea = new Rect(1, 1, 79, 6);
		}

		return onceHolderConfig;
	}

	public static VisualConfig getFlyingHolderConfig() {
		if (flyingHolderConfig == null) {
			flyingHolderConfig = new VisualConfig();
			flyingHolderConfig.imgID = R.drawable.kite;
			flyingHolderConfig.type = VisualType.KitHolder;
			flyingHolderConfig.initialVelocity = new Velocity(0, 0);
			flyingHolderConfig.effectTime = -1;
			flyingHolderConfig.showUpRate = 0.2f;
			flyingHolderConfig.maxShowUpCount = 1;
			flyingHolderConfig.showUpScore = 10000;
			flyingHolderConfig.hitTestArea = new Rect(1, 1, 61, 86);
			flyingHolderConfig.holdOn = new HoldOnInformation(new Point(-20, 0));
		}

		return flyingHolderConfig;
	}

	public static VisualConfig getAvatarConfig() {
		if (avatarConfig == null) {
			avatarConfig = new VisualConfig();
			avatarConfig.imgID = R.drawable.panda;
			avatarConfig.type = VisualType.Avatar;
			avatarConfig.hitTestArea = new Rect(25, 12, 55, 91);
		}

		return avatarConfig;
	}
}